const User = require('model/user')
const ApiError = require('errorException/apiError')
const utils = require('util/utils')
const redis = require('util/redis')
const config = require('@config/config')

// console.log(mongoose.model('zzz', {aa:{type:String},b:{type:Number}}))

module.exports = {
  /** 
   * 用户注册
   */
  addUser: async function(params) {
    const originPassword = params.password
    params.password = await utils.bcrypt(params)
    let user = await User.find({ 
      username: params.username
    })
    if (!user.length) {
      // const user = new User(params)
      // const res = user.save()
      // Mongoose: users.insertOne({ _id: ObjectId("5db0179a4bd5e23e74e540f3"), username: 'xxx', password: 'xxx123', age: 17, __v: 0 }, { session: null })
      // 使用save()方法，需要先实例化为文档，再使用save()方法保存文档。而create()方法，则直接在模型Model上操作，并且可以同时新增多个文档
      params.create_time = new Date().getTime()
      const result = await User.create(params)
      result['password'] = originPassword
      return result
    }
    throw new ApiError('auth.userHasExist')
  },

  /** 
   * 用户登录
   */
  findUser: async function(params) {
    // find指的是查找指定表的所有数据，返回的是数组
    // findOne指的是查找指定表的单条数据，返回一个对象
    const result = await User.findOne({
      username: params.username
    })
    if (result && result.username && result.password) {
      const validatePassword = await utils.compare(params.password, result.password)
      if (validatePassword) { /* 验证密码是否正确 */
        const token = await utils.setToken(result)
        // const data = { 
        //   token: token,
        //   update_time: new Date().getTime()
        // }
        // const res = await User.updateOne({ username: params.username }, { $set: data })
        const response = {
          username: result.username,
          age: result.age,
          token: `${token}`,
          avatar: result.avatar,
          create_time: result.creat_time,
          id: result._id
        }
        await setTokenInCacheUserInfo(response)
        return response
      } else {
        throw new ApiError('auth.psderror')
      }
    }
    throw new ApiError('auth.notExist')
  },

  /** 
   * @description: 修改密码 
   *  
  */
  
  resetPassword: async function(params) {

    // conditions: 查询条件；
    // updateDoc：需要修改的数据, 都是一个对象
    // multi (boolean)： 默认为false。是否更新多个查询记录。
    const data = { 
      password: params.new_password
    }
    const result = await User.findOne({
      username: params.username
    })
    const validatePassword = await utils.compare(params.password, result.password)
    if (validatePassword) { /* 验证密码是否正确 */
      throw new ApiError('auth.passwordRepeat')
    } else {
      const originPassword = params.password
      params.password = await utils.bcrypt(params)
      const result = await User.updateOne({ password: params.password }, { $set: data })
      if (result.ok) {
        return {
          username: result.username,
          password: originPassword
        }
      }
    }
    throw new ApiError('auth.userUpdate')
  }
}

/**
  * @author dven 
  * @description 将token放入userInfo 
  * @param { Object } userInfo 用户信息
*/
  const setTokenInCacheUserInfo = async function(userInfo) {
    /** 
     * 给redis添加前缀，主要是为了区分多个
     * 
     * redis.set(key, value, expire)
     * @param { String } key redis存储的key
     * @param { String } value redis存储的value
     * @param { Number } expire 过期时间
     *  */
    await redis.set(`blog:user:token:${userInfo.username}`, userInfo.token, 'EX', config.expiresIn)
}